        <!DOCTYPE html>
        <html>
        <head>
                <meta charset="utf-8">
        <title>TimeOfImpact class / box2d Library / Dart Documentation</title>
        <link rel="stylesheet" type="text/css"
            href="../styles.css">
        <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800" rel="stylesheet" type="text/css">
        <link rel="shortcut icon" href="../favicon.ico">
        
        </head>
        <body data-library="box2d" data-type="TimeOfImpact">
        <div class="page">
        <div class="header">
          <a href="../index.html"><div class="logo"></div></a>
          <a href="../index.html">Dart Documentation</a>
         &rsaquo; <a href="../box2d.html">box2d</a> &rsaquo; <a href="../box2d/TimeOfImpact.html">TimeOfImpact</a>        <div id="search-box">
          <input type="search" name="q" id="q" autocomplete="off"
              class="search-input" placeholder="Search API">
        </div>
        
      </div>
      <div class="drop-down" id="drop-down"></div>
      
        <div class="nav">
        
</div>
<div class="content">
        <h2><strong>TimeOfImpact</strong>
          class
        </h2>
        
<button id="show-inherited" class="show-inherited">Hide inherited</button>
<div class="doc">
<pre class="source">
class TimeOfImpact {
 static const int MAX_ITERATIONS = 1000;

 static int toiCalls;
 static int toiIters;
 static int toiMaxIters;
 static int toiRootIters;
 static int toiMaxRootIters;

 /** Pool variables */
 final SimplexCache cache;
 final DistanceInput distanceInput;
 final Transform xfA;
 final Transform xfB;
 final DistanceOutput distanceOutput;
 final SeparationFunction fcn;
 final List&lt;int&gt; indexes;
 final Sweep sweepA;
 final Sweep sweepB;

 DefaultWorldPool pool;

 TimeOfImpact._construct(DefaultWorldPool argPool) :
   pool = argPool,
   cache = new SimplexCache(),
   distanceInput = new DistanceInput(),
   xfA = new Transform(),
   xfB = new Transform(),
   distanceOutput = new DistanceOutput(),
   fcn = new SeparationFunction(),
   indexes = new List&lt;int&gt;(2),
   sweepA = new Sweep(),
   sweepB = new Sweep() {
   indexes[0] = 0;
   indexes[1] = 0;
   toiCalls = 0;
   toiIters = 0;
   toiMaxIters = 0;
   toiRootIters = 0;
   toiMaxRootIters = 0;
 }

 /**
  * Compute the upper bound on time before two shapes penetrate. Time is
  * represented as a fraction between [0,tMax]. This uses a swept separating
  * axis and may miss some intermediate, non-tunneling collision. If you
  * change the time interval, you should call this function again.
  * Note: use Distance to compute the contact point and normal at the time
  * of impact.
  */
 void timeOfImpact(TimeOfImpactOutput output, TimeOfImpactInput input) {
   // CCD via the local separating axis method. This seeks progression
   // by computing the largest time at which separation is maintained.
   ++toiCalls;

   output.state = TimeOfImpactOutputState.UNKNOWN;
   output.t = input.tMax;

   DistanceProxy proxyA = input.proxyA;
   DistanceProxy proxyB = input.proxyB;

   sweepA.setFrom(input.sweepA);
   sweepB.setFrom(input.sweepB);

   // Large rotations can make the root finder fail, so we normalize the
   // sweep angles.
   sweepA.normalize();
   sweepB.normalize();

   num tMax = input.tMax;

   num totalRadius = proxyA.radius + proxyB.radius;
   num target = math.max(Settings.LINEAR_SLOP, totalRadius
       - 3.0 * Settings.LINEAR_SLOP);
   num tolerance = 0.25 * Settings.LINEAR_SLOP;

   assert (target &gt; tolerance);

   num t1 = 0;
   int iter = 0;

   cache.count = 0;
   distanceInput.proxyA = input.proxyA;
   distanceInput.proxyB = input.proxyB;
   distanceInput.useRadii = false;

   // The outer loop progressively attempts to compute new separating axes.
   // This loop terminates when an axis is repeated (no progress is made).
   while (true) {
     sweepA.getTransform(xfA, t1);
     sweepB.getTransform(xfB, t1);
     // Get the distance between shapes. We can also use the results
     // to get a separating axis
     distanceInput.transformA = xfA;
     distanceInput.transformB = xfB;
     pool.distance.computeDistance(distanceOutput, cache, distanceInput);

     // If the shapes are overlapped, we give up on continuous collision.
     if (distanceOutput._distance &lt;= 0) {
       // Failure!
       output.state = TimeOfImpactOutputState.OVERLAPPED;
       output.t = 0;
       break;
     }

     if (distanceOutput._distance &lt; target + tolerance) {
       // Victory!
       output.state = TimeOfImpactOutputState.TOUCHING;
       output.t = t1;
       break;
     }

     // Initialize the separating axis.
     fcn.initialize(cache, proxyA, sweepA, proxyB, sweepB, t1);

     // Compute the TimeOfImpact on the separating axis. We do this by successively
     // resolving the deepest point. This loop is bounded by the number of
     // vertices.
     bool done = false;
     num t2 = tMax;
     int pushBackIter = 0;
     while (true) {

       // Find the deepest point at t2. Store the witness point indices.
       num s2 = fcn.findMinSeparation(indexes, t2);
       // Is the configuration separated?
       if (s2 &gt; target + tolerance) {
         // Victory!
         output.state = TimeOfImpactOutputState.SEPARATED;
         output.t = tMax;
         done = true;
         break;
       }

       // Has the separation reached tolerance?
       if (s2 &gt; target - tolerance) {
         // Advance the sweeps
         t1 = t2;
         break;
       }

       // Compute the initial separation of the witness points.
       num s1 = fcn.evaluate(indexes[0], indexes[1], t1);
       // Check for initial overlap. This might happen if the root finder
       // runs out of iterations.
       if (s1 &lt; target - tolerance) {
         output.state = TimeOfImpactOutputState.FAILED;
         output.t = t1;
         done = true;
         break;
       }

       // Check for touching
       if (s1 &lt;= target + tolerance) {
         // Victory! t1 should hold the TimeOfImpact (could be 0.0).
         output.state = TimeOfImpactOutputState.TOUCHING;
         output.t = t1;
         done = true;
         break;
       }

       // Compute 1D root of: f(x) - target = 0
       int rootIterCount = 0;
       num a1 = t1, a2 = t2;
       while (true) {
         // Use a mix of the secant rule and bisection.
         num t;
         if ((rootIterCount &amp; 1) == 1) {
           // Secant rule to improve convergence.
           t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);
         } else {
           // Bisection to guarantee progress.
           t = 0.5 * (a1 + a2);
         }

         num s = fcn.evaluate(indexes[0], indexes[1], t);

         if ((s - target).abs() &lt; tolerance) {
           // t2 holds a tentative value for t1
           t2 = t;
           break;
         }

         // Ensure we continue to bracket the root.
         if (s &gt; target) {
           a1 = t;
           s1 = s;
         } else {
           a2 = t;
           s2 = s;
         }

         ++rootIterCount;
         ++toiRootIters;

         // djm: whats with this? put in settings?
         if (rootIterCount == 50) {
           break;
         }
       }

       toiMaxRootIters = math.max(toiMaxRootIters, rootIterCount);

       ++pushBackIter;

       if (pushBackIter == Settings.MAX_POLYGON_VERTICES) {
         break;
       }
     }

     ++iter;
     ++toiIters;

     if (done)
       break;

     if (iter == MAX_ITERATIONS) {
       // Root finder got stuck. Semi-victory.
       output.state = TimeOfImpactOutputState.FAILED;
       output.t = t1;
       break;
     }
   }

   toiMaxIters = math.max(toiMaxIters, iter);
 }
}
</pre>
</div>
<div>
<h3>Static Properties</h3>
<div class="field"><h4 id="MAX_ITERATIONS">
<button class="show-code">Code</button>
const int         <strong>MAX_ITERATIONS</strong> <a class="anchor-link"
            href="#MAX_ITERATIONS"
            title="Permalink to TimeOfImpact.MAX_ITERATIONS">#</a>
        </h4>
        <div class="doc">
<pre class="source">
MAX_ITERATIONS = 1000
</pre>
</div>
</div>
<div class="field"><h4 id="toiCalls">
<button class="show-code">Code</button>
int         <strong>toiCalls</strong> <a class="anchor-link"
            href="#toiCalls"
            title="Permalink to TimeOfImpact.toiCalls">#</a>
        </h4>
        <div class="doc">
<pre class="source">
toiCalls
</pre>
</div>
</div>
<div class="field"><h4 id="toiIters">
<button class="show-code">Code</button>
int         <strong>toiIters</strong> <a class="anchor-link"
            href="#toiIters"
            title="Permalink to TimeOfImpact.toiIters">#</a>
        </h4>
        <div class="doc">
<pre class="source">
toiIters
</pre>
</div>
</div>
<div class="field"><h4 id="toiMaxIters">
<button class="show-code">Code</button>
int         <strong>toiMaxIters</strong> <a class="anchor-link"
            href="#toiMaxIters"
            title="Permalink to TimeOfImpact.toiMaxIters">#</a>
        </h4>
        <div class="doc">
<pre class="source">
toiMaxIters
</pre>
</div>
</div>
<div class="field"><h4 id="toiMaxRootIters">
<button class="show-code">Code</button>
int         <strong>toiMaxRootIters</strong> <a class="anchor-link"
            href="#toiMaxRootIters"
            title="Permalink to TimeOfImpact.toiMaxRootIters">#</a>
        </h4>
        <div class="doc">
<pre class="source">
toiMaxRootIters
</pre>
</div>
</div>
<div class="field"><h4 id="toiRootIters">
<button class="show-code">Code</button>
int         <strong>toiRootIters</strong> <a class="anchor-link"
            href="#toiRootIters"
            title="Permalink to TimeOfImpact.toiRootIters">#</a>
        </h4>
        <div class="doc">
<pre class="source">
toiRootIters
</pre>
</div>
</div>
</div>
<div>
<h3>Properties</h3>
<div class="field"><h4 id="cache">
<button class="show-code">Code</button>
final <a href="../box2d/SimplexCache.html">SimplexCache</a>         <strong>cache</strong> <a class="anchor-link"
            href="#cache"
            title="Permalink to TimeOfImpact.cache">#</a>
        </h4>
        <div class="doc">
<pre class="source">
cache
</pre>
</div>
</div>
<div class="field"><h4 id="distanceInput">
<button class="show-code">Code</button>
final <a href="../box2d/DistanceInput.html">DistanceInput</a>         <strong>distanceInput</strong> <a class="anchor-link"
            href="#distanceInput"
            title="Permalink to TimeOfImpact.distanceInput">#</a>
        </h4>
        <div class="doc">
<pre class="source">
distanceInput
</pre>
</div>
</div>
<div class="field"><h4 id="distanceOutput">
<button class="show-code">Code</button>
final <a href="../box2d/DistanceOutput.html">DistanceOutput</a>         <strong>distanceOutput</strong> <a class="anchor-link"
            href="#distanceOutput"
            title="Permalink to TimeOfImpact.distanceOutput">#</a>
        </h4>
        <div class="doc">
<pre class="source">
distanceOutput
</pre>
</div>
</div>
<div class="field"><h4 id="fcn">
<button class="show-code">Code</button>
final <a href="../box2d/SeparationFunction.html">SeparationFunction</a>         <strong>fcn</strong> <a class="anchor-link"
            href="#fcn"
            title="Permalink to TimeOfImpact.fcn">#</a>
        </h4>
        <div class="doc">
<pre class="source">
fcn
</pre>
</div>
</div>
<div class="field"><h4 id="indexes">
<button class="show-code">Code</button>
final List&lt;int&gt;         <strong>indexes</strong> <a class="anchor-link"
            href="#indexes"
            title="Permalink to TimeOfImpact.indexes">#</a>
        </h4>
        <div class="doc">
<pre class="source">
indexes
</pre>
</div>
</div>
<div class="field"><h4 id="pool">
<button class="show-code">Code</button>
<a href="../box2d/DefaultWorldPool.html">DefaultWorldPool</a>         <strong>pool</strong> <a class="anchor-link"
            href="#pool"
            title="Permalink to TimeOfImpact.pool">#</a>
        </h4>
        <div class="doc">
<pre class="source">
pool
</pre>
</div>
</div>
<div class="field"><h4 id="sweepA">
<button class="show-code">Code</button>
final <a href="../box2d/Sweep.html">Sweep</a>         <strong>sweepA</strong> <a class="anchor-link"
            href="#sweepA"
            title="Permalink to TimeOfImpact.sweepA">#</a>
        </h4>
        <div class="doc">
<pre class="source">
sweepA
</pre>
</div>
</div>
<div class="field"><h4 id="sweepB">
<button class="show-code">Code</button>
final <a href="../box2d/Sweep.html">Sweep</a>         <strong>sweepB</strong> <a class="anchor-link"
            href="#sweepB"
            title="Permalink to TimeOfImpact.sweepB">#</a>
        </h4>
        <div class="doc">
<pre class="source">
sweepB
</pre>
</div>
</div>
<div class="field"><h4 id="xfA">
<button class="show-code">Code</button>
final <a href="../box2d/Transform.html">Transform</a>         <strong>xfA</strong> <a class="anchor-link"
            href="#xfA"
            title="Permalink to TimeOfImpact.xfA">#</a>
        </h4>
        <div class="doc">
<pre class="source">
xfA
</pre>
</div>
</div>
<div class="field"><h4 id="xfB">
<button class="show-code">Code</button>
final <a href="../box2d/Transform.html">Transform</a>         <strong>xfB</strong> <a class="anchor-link"
            href="#xfB"
            title="Permalink to TimeOfImpact.xfB">#</a>
        </h4>
        <div class="doc">
<pre class="source">
xfB
</pre>
</div>
</div>
</div>
<div>
<h3>Methods</h3>
<div class="method"><h4 id="timeOfImpact">
<button class="show-code">Code</button>
void <strong>timeOfImpact</strong>(<a href="../box2d/TimeOfImpactOutput.html">TimeOfImpactOutput</a> output, <a href="../box2d/TimeOfImpactInput.html">TimeOfImpactInput</a> input) <a class="anchor-link" href="#timeOfImpact"
              title="Permalink to TimeOfImpact.timeOfImpact">#</a></h4>
<div class="doc">
<p>Compute the upper bound on time before two shapes penetrate. Time is
represented as a fraction between <code>0,tMax</code>. This uses a swept separating
axis and may miss some intermediate, non-tunneling collision. If you
change the time interval, you should call this function again.
Note: use Distance to compute the contact point and normal at the time
of impact.</p>
<pre class="source">
void timeOfImpact(TimeOfImpactOutput output, TimeOfImpactInput input) {
 // CCD via the local separating axis method. This seeks progression
 // by computing the largest time at which separation is maintained.
 ++toiCalls;

 output.state = TimeOfImpactOutputState.UNKNOWN;
 output.t = input.tMax;

 DistanceProxy proxyA = input.proxyA;
 DistanceProxy proxyB = input.proxyB;

 sweepA.setFrom(input.sweepA);
 sweepB.setFrom(input.sweepB);

 // Large rotations can make the root finder fail, so we normalize the
 // sweep angles.
 sweepA.normalize();
 sweepB.normalize();

 num tMax = input.tMax;

 num totalRadius = proxyA.radius + proxyB.radius;
 num target = math.max(Settings.LINEAR_SLOP, totalRadius
     - 3.0 * Settings.LINEAR_SLOP);
 num tolerance = 0.25 * Settings.LINEAR_SLOP;

 assert (target &gt; tolerance);

 num t1 = 0;
 int iter = 0;

 cache.count = 0;
 distanceInput.proxyA = input.proxyA;
 distanceInput.proxyB = input.proxyB;
 distanceInput.useRadii = false;

 // The outer loop progressively attempts to compute new separating axes.
 // This loop terminates when an axis is repeated (no progress is made).
 while (true) {
   sweepA.getTransform(xfA, t1);
   sweepB.getTransform(xfB, t1);
   // Get the distance between shapes. We can also use the results
   // to get a separating axis
   distanceInput.transformA = xfA;
   distanceInput.transformB = xfB;
   pool.distance.computeDistance(distanceOutput, cache, distanceInput);

   // If the shapes are overlapped, we give up on continuous collision.
   if (distanceOutput._distance &lt;= 0) {
     // Failure!
     output.state = TimeOfImpactOutputState.OVERLAPPED;
     output.t = 0;
     break;
   }

   if (distanceOutput._distance &lt; target + tolerance) {
     // Victory!
     output.state = TimeOfImpactOutputState.TOUCHING;
     output.t = t1;
     break;
   }

   // Initialize the separating axis.
   fcn.initialize(cache, proxyA, sweepA, proxyB, sweepB, t1);

   // Compute the TimeOfImpact on the separating axis. We do this by successively
   // resolving the deepest point. This loop is bounded by the number of
   // vertices.
   bool done = false;
   num t2 = tMax;
   int pushBackIter = 0;
   while (true) {

     // Find the deepest point at t2. Store the witness point indices.
     num s2 = fcn.findMinSeparation(indexes, t2);
     // Is the configuration separated?
     if (s2 &gt; target + tolerance) {
       // Victory!
       output.state = TimeOfImpactOutputState.SEPARATED;
       output.t = tMax;
       done = true;
       break;
     }

     // Has the separation reached tolerance?
     if (s2 &gt; target - tolerance) {
       // Advance the sweeps
       t1 = t2;
       break;
     }

     // Compute the initial separation of the witness points.
     num s1 = fcn.evaluate(indexes[0], indexes[1], t1);
     // Check for initial overlap. This might happen if the root finder
     // runs out of iterations.
     if (s1 &lt; target - tolerance) {
       output.state = TimeOfImpactOutputState.FAILED;
       output.t = t1;
       done = true;
       break;
     }

     // Check for touching
     if (s1 &lt;= target + tolerance) {
       // Victory! t1 should hold the TimeOfImpact (could be 0.0).
       output.state = TimeOfImpactOutputState.TOUCHING;
       output.t = t1;
       done = true;
       break;
     }

     // Compute 1D root of: f(x) - target = 0
     int rootIterCount = 0;
     num a1 = t1, a2 = t2;
     while (true) {
       // Use a mix of the secant rule and bisection.
       num t;
       if ((rootIterCount &amp; 1) == 1) {
         // Secant rule to improve convergence.
         t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);
       } else {
         // Bisection to guarantee progress.
         t = 0.5 * (a1 + a2);
       }

       num s = fcn.evaluate(indexes[0], indexes[1], t);

       if ((s - target).abs() &lt; tolerance) {
         // t2 holds a tentative value for t1
         t2 = t;
         break;
       }

       // Ensure we continue to bracket the root.
       if (s &gt; target) {
         a1 = t;
         s1 = s;
       } else {
         a2 = t;
         s2 = s;
       }

       ++rootIterCount;
       ++toiRootIters;

       // djm: whats with this? put in settings?
       if (rootIterCount == 50) {
         break;
       }
     }

     toiMaxRootIters = math.max(toiMaxRootIters, rootIterCount);

     ++pushBackIter;

     if (pushBackIter == Settings.MAX_POLYGON_VERTICES) {
       break;
     }
   }

   ++iter;
   ++toiIters;

   if (done)
     break;

   if (iter == MAX_ITERATIONS) {
     // Root finder got stuck. Semi-victory.
     output.state = TimeOfImpactOutputState.FAILED;
     output.t = t1;
     break;
   }
 }

 toiMaxIters = math.max(toiMaxIters, iter);
}
</pre>
</div>
</div>
</div>
        </div>
        <div class="clear"></div>
        </div>
        <div class="footer">
          
        </div>
        <script async src="../client-live-nav.js"></script>
        </body></html>
        
